/*
 * Copyright (C) 2023 Realtek Semiconductor Corp.
 * All Rights Reserved.
 *
 * This program is the proprietary software of Realtek Semiconductor
 * Corporation and/or its licensors, and only be used, duplicated,
 * modified or distributed under the authorized license from Realtek.
 *
 * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER
 * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 *
 * Purpose : Definition of ME handler: PPTP FTTR P2MP Port   (65506)
 *
 * Feature : The file includes the following modules and sub-modules
 *           (1) ME handler: PPTP FTTR P2MP Port   (65506)
 */

#include "app_basic.h"
#include "omci_task.h"
#include "feature_mgmt.h"

MIB_TABLE_INFO_T gMibAnigExtentionTableInfo;
MIB_ATTR_INFO_T  gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ATTR_NUM];
MIB_TABLE_ANIG_EXTENTION_T gMibAnigExtentionRow;
MIB_TABLE_OPER_T gMibAnigExtentionOper;

static GOS_ERROR_CODE omci_mib_anig_extention_reset(UINT32 args_num, ...)
{
    INT32 portId = 1;
    MIB_TABLE_ANIG_EXTENTION_T mibAnigExtention;
    UINT16 anigEntityID = (UINT16)((TXC_CARDHLD_PON_SLOT_TYPE_ID << 8) | portId); 
    CHAR boaMibVal[OMCI_BOA_MIB_BUFFER_LEN];
    UINT32  flag = 0,ponSpeedCap = 0,ponSpeedSupportCnt = 0;

    MIB_Default(MIB_TABLE_ANIG_EXTENTION_INDEX, &mibAnigExtention, sizeof(MIB_TABLE_ANIG_EXTENTION_T));
  
    mibAnigExtention.EntityID   = 0;
    mibAnigExtention.AnigPoint  = anigEntityID;

    switch(gInfo.ponSpeed)
    {
        case OMCI_PON_SPEED_GPON:
            mibAnigExtention.AniCapability = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            mibAnigExtention.AniMode = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            mibAnigExtention.CurrentAniMode = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            break;
        case OMCI_PON_SPEED_XGPON1:
            mibAnigExtention.AniCapability = MIB_ANIG_EXTENTION_ANI_MODE_XGPON;
            mibAnigExtention.AniMode = MIB_ANIG_EXTENTION_ANI_MODE_XGPON;
            mibAnigExtention.CurrentAniMode = MIB_ANIG_EXTENTION_ANI_MODE_XGPON;
            break;
        case OMCI_PON_SPEED_XGSPON:
            mibAnigExtention.AniCapability = MIB_ANIG_EXTENTION_ANI_MODE_XGSPON;
            mibAnigExtention.AniMode = MIB_ANIG_EXTENTION_ANI_MODE_XGSPON;
            mibAnigExtention.CurrentAniMode = MIB_ANIG_EXTENTION_ANI_MODE_XGSPON;
            break;
        default:
            mibAnigExtention.AniCapability = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            mibAnigExtention.AniMode = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            mibAnigExtention.CurrentAniMode = MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            break;
    }

    if (GOS_OK == omci_get_boa_mib_value_by_name("PON_DETECT_CONTROL_FLAG", boaMibVal))
    {
        flag = strtol(boaMibVal, NULL, 0);
        if(IS_RUN_PON_SPEED_AUTO(flag))
            mibAnigExtention.AniMode = MIB_ANIG_EXTENTION_ANI_MODE_AUTO;
    }    

    if (GOS_OK == omci_get_boa_mib_value_by_name("PON_DETECT_AVAILABLE_GPON_FLAG", boaMibVal))
    {
        flag = strtol(boaMibVal, NULL, 0);
        if(IS_SUPPORT_PON_SPEED_GPON(flag))
        {
            ponSpeedCap |= MIB_ANIG_EXTENTION_ANI_MODE_GPON;
            ponSpeedSupportCnt++;
        }

        if(IS_SUPPORT_PON_SPEED_XGPON(flag))
        {
            ponSpeedCap |= MIB_ANIG_EXTENTION_ANI_MODE_XGPON;           
            ponSpeedSupportCnt++;
        }

        if(IS_SUPPORT_PON_SPEED_XGSPON(flag))
        {
            ponSpeedCap |= MIB_ANIG_EXTENTION_ANI_MODE_XGSPON;
            ponSpeedSupportCnt++;
        }

        if(ponSpeedSupportCnt > 1)
        {
            ponSpeedCap |= MIB_ANIG_EXTENTION_ANI_MODE_AUTO;            
        }

    }

    if(ponSpeedCap != 0)
    {
        mibAnigExtention.AniCapability = ponSpeedCap;      
    }    


    OMCI_LOG(OMCI_LOG_LEVEL_INFO, "Resetting MIB: ANIG Extention EntityID:0x%04x", mibAnigExtention.EntityID);

    GOS_ASSERT(GOS_OK == MIB_Set(MIB_TABLE_ANIG_EXTENTION_INDEX, &mibAnigExtention, sizeof(MIB_TABLE_ANIG_EXTENTION_T)));
    OMCI_MeOperCfg(MIB_TABLE_ANIG_EXTENTION_INDEX, NULL, &mibAnigExtention, MIB_ADD,
        omci_GetOltAccAttrSet(MIB_TABLE_ANIG_EXTENTION_INDEX, OMCI_ME_ATTR_ACCESS_SBC), OMCI_MSG_BASELINE_PRI_LOW);


    return GOS_OK;
 
}

GOS_ERROR_CODE omci_mib_anig_extention_drv_cfg(void              *pOldRow,
                            void            *pNewRow,
                            MIB_OPERA_TYPE  operationType,
                            MIB_ATTRS_SET   attrSet,
                            UINT32          pri)
{
    GOS_ERROR_CODE      ret = GOS_OK;
    MIB_TABLE_ANIG_EXTENTION_T    *pOldAnigExtention=NULL, *pNewAnigExtention=NULL;
    omci_event_msg_t    omciEventMsg;

    pOldAnigExtention = (MIB_TABLE_ANIG_EXTENTION_T *)pOldRow;
    pNewAnigExtention = (MIB_TABLE_ANIG_EXTENTION_T *)pNewRow;

    switch (operationType)
    {
        case MIB_SET:
            if (MIB_IsInAttrSet(&attrSet, MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX) &&
                pOldAnigExtention->AniMode != pNewAnigExtention->AniMode)
            {
                if(0x0000 ==(pNewAnigExtention->AniMode & pOldAnigExtention->AniCapability))
                {
                    OMCI_LOG (OMCI_LOG_LEVEL_WARN, "AniMode: %d is unspport", pNewAnigExtention->AniMode);
                    return (GOS_ERR_NOTSUPPORT);             

                }        

                memset(&omciEventMsg, 0, sizeof(omci_event_msg_t));
                omciEventMsg.subType = OMCI_EVENT_TYPE_PON_SPEED_CHANGE;
                switch(pNewAnigExtention->AniMode)
                {
                    case MIB_ANIG_EXTENTION_ANI_MODE_AUTO:
                        omciEventMsg.status = BCAST_OMCI_PON_SPEED_AUTO;
                        break;
                    case MIB_ANIG_EXTENTION_ANI_MODE_GPON:
                        omciEventMsg.status = BCAST_OMCI_PON_SPEED_GPON;        
                        break;
                    case MIB_ANIG_EXTENTION_ANI_MODE_XGPON:
                        omciEventMsg.status = BCAST_OMCI_PON_SPEED_XGPON;        
                        break;
                    case MIB_ANIG_EXTENTION_ANI_MODE_XGSPON:
                       omciEventMsg.status = BCAST_OMCI_PON_SPEED_XGSPON;        
                       break;
                    default: 
                        return GOS_OK;
                }
                if (GOS_OK != omci_wrapper_sendOmciEvent(&omciEventMsg))
                {
                    return (GOS_FAIL);  
                }

            }
            break;    
        default:
            break;
    }

    return ret;    
}





GOS_ERROR_CODE mibTable_init(MIB_TABLE_INDEX tableId)
{
    UINT8 proprietary_mib_cb_bitmask = 0;
    UINT8 isIgnore = 0;

    if(GOS_OK == omci_ignore_mib_table_check(OMCI_ME_CLASS_ANIG_EXTENTION, OMCI_ME_CLASS_SUB_DEFAULT, &isIgnore))
    {
        if(isIgnore)
        {
            OMCI_PRINT("Ignore classId:%d", OMCI_ME_CLASS_ANIG_EXTENTION);
            return GOS_FAIL;
        }
    }

    gMibAnigExtentionTableInfo.Name = "AnigExtention";
    gMibAnigExtentionTableInfo.ShortName = "AnigExtention";
    gMibAnigExtentionTableInfo.Desc = "ANIG Extenetion";
    gMibAnigExtentionTableInfo.ClassId = (UINT32)(OMCI_ME_CLASS_ANIG_EXTENTION);
    gMibAnigExtentionTableInfo.InitType = (UINT32)(OMCI_ME_INIT_TYPE_ONU);
    gMibAnigExtentionTableInfo.StdType = (UINT32)(OMCI_ME_TYPE_PROPRIETARY);
    gMibAnigExtentionTableInfo.ActionType = (UINT32)(OMCI_ME_ACTION_SET | OMCI_ME_ACTION_GET);
    gMibAnigExtentionTableInfo.pAttributes = &(gMibAnigExtentionAttrInfo[0]);
    gMibAnigExtentionTableInfo.attrNum = MIB_TABLE_ANIG_EXTENTION_ATTR_NUM;
    gMibAnigExtentionTableInfo.entrySize = sizeof(MIB_TABLE_ANIG_EXTENTION_T);
    gMibAnigExtentionTableInfo.pDefaultRow = &gMibAnigExtentionRow;
    
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].Name = "EntityID";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].Name = "AnigPoint";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].Name = "AniCapability";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Name = "AniMode";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Name = "CurrentAniMode";

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].Desc = "Entity ID";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].Desc = "ANIG Point";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].Desc = "ANI Capability";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Desc = "ANI Mode";
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Desc = "Current ANI Capability";

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].DataType = MIB_ATTR_TYPE_UINT16;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].DataType = MIB_ATTR_TYPE_UINT16;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].DataType = MIB_ATTR_TYPE_UINT16;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].DataType = MIB_ATTR_TYPE_UINT16;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].DataType = MIB_ATTR_TYPE_UINT16;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].Len = 2;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].Len = 2;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].Len = 2;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Len = 2;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].Len = 2;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].IsIndex = TRUE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].IsIndex = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].IsIndex = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].IsIndex = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].IsIndex = FALSE;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].MibSave = TRUE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].MibSave = TRUE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].MibSave = TRUE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].MibSave = TRUE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].MibSave = TRUE;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].OutStyle = MIB_ATTR_OUT_HEX;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].OutStyle = MIB_ATTR_OUT_HEX;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].OutStyle = MIB_ATTR_OUT_HEX;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OutStyle = MIB_ATTR_OUT_HEX;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OutStyle = MIB_ATTR_OUT_HEX;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].OltAcc = OMCI_ME_ATTR_ACCESS_READ;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].OltAcc = OMCI_ME_ATTR_ACCESS_READ;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].OltAcc = OMCI_ME_ATTR_ACCESS_READ;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OltAcc = OMCI_ME_ATTR_ACCESS_READ | OMCI_ME_ATTR_ACCESS_WRITE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OltAcc = OMCI_ME_ATTR_ACCESS_READ;

    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].AvcFlag = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].AvcFlag = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].AvcFlag = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].AvcFlag = FALSE;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].AvcFlag = FALSE;


    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ENTITYID_INDEX - MIB_TABLE_FIRST_INDEX].OptionType = OMCI_ME_ATTR_TYPE_MANDATORY;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_POINT_INDEX - MIB_TABLE_FIRST_INDEX].OptionType = OMCI_ME_ATTR_TYPE_MANDATORY;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANIG_CAPABILITY_INDEX - MIB_TABLE_FIRST_INDEX].OptionType = OMCI_ME_ATTR_TYPE_MANDATORY;
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OptionType = OMCI_ME_ATTR_TYPE_MANDATORY;     
    gMibAnigExtentionAttrInfo[MIB_TABLE_ANIG_EXTENTION_CURR_ANI_MODE_INDEX - MIB_TABLE_FIRST_INDEX].OptionType = OMCI_ME_ATTR_TYPE_MANDATORY;

    memset(&gMibAnigExtentionRow, 0x00, sizeof(gMibAnigExtentionRow));


    memset(&gMibAnigExtentionOper, 0x0, sizeof(MIB_TABLE_OPER_T));
    gMibAnigExtentionOper.meOperDrvCfg = omci_mib_anig_extention_drv_cfg;
    gMibAnigExtentionOper.meOperConnCheck = NULL;
    gMibAnigExtentionOper.meOperDump = omci_mib_oper_dump_default_handler;
    gMibAnigExtentionOper.meOperConnCfg = NULL;
    gMibAnigExtentionOper.meOperAlarmHandler = NULL;
    gMibAnigExtentionOper.meOperTestHandler = NULL;
    gMibAnigExtentionOper.meOperCb[PROPRIETARY_MIB_CB_RESET] = omci_mib_anig_extention_reset;

    MIB_TABLE_ANIG_EXTENTION_INDEX = tableId;
    MIB_InfoRegister(tableId,&gMibAnigExtentionTableInfo,&gMibAnigExtentionOper);

    proprietary_mib_cb_bitmask = (1 << PROPRIETARY_MIB_CB_RESET);
    MIB_Proprietary_Reg(tableId, proprietary_mib_cb_bitmask);

    return GOS_OK;
}
